home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP05.ZIP / CHAP05 / SCHMOO / POLYLINE.CPP < prev    next >
C/C++ Source or Header  |  1993-06-17  |  30KB  |  1,347 lines

  1. /*
  2.  * POLYLINE.CPP
  3.  * Modified for Chapter 5.
  4.  *
  5.  * Implementation of the CPolyline class.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17.  
  18. #include "schmoo.h"
  19.  
  20.  
  21.  
  22. /*
  23.  * CPolyline:CPolyline
  24.  * CPolyline::~CPolyline
  25.  *
  26.  * Constructor Parameters:
  27.  *  hInst           HINSTANCE of the application we're in.
  28.  */
  29.  
  30. CPolyline::CPolyline(HINSTANCE hInst)
  31.     : CWindow(hInst)
  32.     {
  33.     m_pAdv=NULL;
  34.     m_hWnd=NULL;
  35.     return;
  36.     }
  37.  
  38.  
  39. CPolyline::~CPolyline(void)
  40.     {
  41.     return;
  42.     }
  43.  
  44.  
  45.  
  46.  
  47.  
  48. /*
  49.  * CPolyline::FInit
  50.  *
  51.  * Purpose:
  52.  *  Instantiates a polyline window within a given parent.  The
  53.  *  parent may be a main application window, could be an MDI child
  54.  *  window. We really do not care.
  55.  *
  56.  * Parameters:
  57.  *  hWndParent      HWND of the parent of this window
  58.  *  pRect           LPRECT that this window should occupy
  59.  *  dwStyle         DWORD containing the window's style flags
  60.  *  uID             UINT ID to associate with this window
  61.  *  pAdv            LPCPolylineAdviseSink of the sink wanting our notifications.
  62.  *
  63.  * Return Value:
  64.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  65.  */
  66.  
  67. BOOL CPolyline::FInit(HWND hWndParent, LPRECT pRect, DWORD dwStyle, UINT uID
  68.     , LPCPolylineAdviseSink pAdv)
  69.     {
  70.     m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPOLYLINE
  71.         , SZCLASSPOLYLINE, dwStyle, pRect->left, pRect->top
  72.         , pRect->right-pRect->left, pRect->bottom-pRect->top
  73.         , hWndParent, (HMENU)uID, m_hInst, (LPVOID)this);
  74.  
  75.     if (NULL!=m_hWnd)
  76.         m_pAdv=pAdv;
  77.  
  78.     return (NULL!=m_hWnd);
  79.     }
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87. /*
  88.  * CPolyline::New
  89.  *
  90.  * Purpose:
  91.  *  Cleans out and reinitializes the data to defaults.
  92.  *
  93.  * Parameters:
  94.  *  None
  95.  *
  96.  * Return Value:
  97.  *  None
  98.  */
  99.  
  100. void CPolyline::New(void)
  101.     {
  102.     UINT        i;
  103.  
  104.     m_pl.wVerMaj=VERSIONMAJOR;
  105.     m_pl.wVerMin=VERSIONMINOR;
  106.  
  107.     //Our rectangle is the size of our window's client area.
  108.     GetClientRect(m_hWnd, &m_pl.rc);
  109.  
  110.     //Clean out the POLYLINE structure and repaint the window.
  111.     for (i=0; i< CPOLYLINEPOINTS; i++)
  112.         {
  113.         m_pl.rgpt[i].x=0;
  114.         m_pl.rgpt[i].y=0;
  115.         }
  116.  
  117.     m_pl.cPoints      =0;
  118.     m_pl.rgbBackground=GetSysColor(COLOR_WINDOW);
  119.     m_pl.rgbLine      =GetSysColor(COLOR_WINDOWTEXT);
  120.     m_pl.iLineStyle   =PS_SOLID;
  121.  
  122.     InvalidateRect(m_hWnd, NULL, TRUE);
  123.     UpdateWindow(m_hWnd);
  124.  
  125.     //Inform the advise sink of this data change.
  126.     if (NULL!=m_pAdv)
  127.         m_pAdv->OnDataChange();
  128.  
  129.     return;
  130.     }
  131.  
  132.  
  133.  
  134.  
  135. /*
  136.  * CPolyline::Undo
  137.  *
  138.  * Purpose:
  139.  *  Reverses previous actions in a Polyline.
  140.  *
  141.  * Parameters:
  142.  *  None
  143.  *
  144.  * Return Value:
  145.  *  BOOL            TRUE if we can Undo more, FALSE otherwise.
  146.  */
  147.  
  148. BOOL CPolyline::Undo(void)
  149.     {
  150.     //Decrement the number of active points and repaint.
  151.     if (m_pl.cPoints > 0)
  152.         {
  153.         m_pl.cPoints--;
  154.         InvalidateRect(m_hWnd, NULL, TRUE);
  155.         UpdateWindow(m_hWnd);
  156.         }
  157.  
  158.     if (NULL!=m_pAdv)
  159.         m_pAdv->OnPointChange();
  160.  
  161.     //Return if we can undo any more.
  162.     return (0!=m_pl.cPoints);
  163.     }
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170. //CHAPTER5MOD
  171.  
  172.  
  173. /*
  174.  * CPolyline::ReadFromStorage
  175.  *
  176.  * Purpose:
  177.  *  Loads our data (any known version) from an IStoraeg returning
  178.  *  the version number of the data or an error value.
  179.  *
  180.  * Parameters:
  181.  *  pIStorage       LPSTORAGE from which we'll read.
  182.  *
  183.  * Return Value:
  184.  *  LONG            Version number or negative POLYLINE_E_* value.
  185.  */
  186.  
  187. LONG CPolyline::ReadFromStorage(LPSTORAGE pIStorage)
  188.     {
  189.     POLYLINEDATA    pl;
  190.     ULONG           cb=-1;
  191.     ULONG           cbExpect=0;
  192.     LPSTREAM        pIStream;
  193.     HRESULT         hr;
  194.     LARGE_INTEGER   li;
  195.  
  196.     if (NULL==pIStorage)
  197.         return POLYLINE_E_READFAILURE;
  198.  
  199.     //Open the CONTENTS stream
  200.     hr=pIStorage->OpenStream("CONTENTS", 0, STGM_DIRECT | STGM_READ
  201.         | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
  202.  
  203.     if (FAILED(hr))
  204.         return POLYLINE_E_READFAILURE;
  205.  
  206.     //Read version numbers and seek back to file beginning.
  207.     hr=pIStream->Read((LPVOID)&pl, 2*sizeof(WORD), &cb);
  208.  
  209.     if (FAILED(hr) || 2*sizeof(WORD)!=cb)
  210.         {
  211.         pIStream->Release();
  212.         return POLYLINE_E_READFAILURE;
  213.         }
  214.  
  215.     LISet32(li, 0);
  216.     pIStream->Seek(li, STREAM_SEEK_SET, NULL);
  217.  
  218.     /*
  219.      * For version 2.0, read the entire file.  For version 1.0 read
  220.      * the file up to CBPOLYLINEDATAVER10.  For anything else, give an
  221.      * error.
  222.      */
  223.  
  224.     switch (pl.wVerMaj)
  225.         {
  226.         case VERSIONMAJOR:  //2.x
  227.             switch (pl.wVerMin)
  228.                 {
  229.                 case VERSIONMINOR:  //2.0
  230.                     cbExpect=CBPOLYLINEDATA;
  231.                     break;
  232.  
  233.                 default:
  234.                     break;
  235.                 }
  236.             break;
  237.  
  238.         case 1: //1.x
  239.             switch (pl.wVerMin)
  240.                 {
  241.                 case 0:  //1.0
  242.                     cbExpect=CBPOLYLINEDATA10;
  243.                     break;
  244.  
  245.                 default:
  246.                     break;
  247.                 }
  248.             break;
  249.  
  250.         default:
  251.             break;
  252.         }
  253.  
  254.     if (0==cbExpect)
  255.         {
  256.         pIStream->Release();
  257.         return POLYLINE_E_UNSUPPORTEDVERSION;
  258.         }
  259.  
  260.     hr=pIStream->Read((LPVOID)&pl, cbExpect, &cb);
  261.     pIStream->Release();
  262.  
  263.     if (cbExpect!=cb)
  264.         return POLYLINE_E_READFAILURE;
  265.  
  266.     /*
  267.      * If we loaded successfully, make the data current.  By using DataSet
  268.      * we centralize our version upgrading.  We size the polyline window
  269.      * to the data AND notify the document so it sizes to the polyline.
  270.      */
  271.     DataSet(&pl, TRUE, TRUE);
  272.  
  273.     //Return what version we just loaded.
  274.     return MAKELONG(pl.wVerMin, pl.wVerMaj);
  275.     }
  276.  
  277.  
  278.  
  279.  
  280. /*
  281.  * CPolyline::WriteToStorage
  282.  *
  283.  * Purpose:
  284.  *  Ignorantly writes our current data into an storage in a particular
  285.  *  version.
  286.  *
  287.  * Parameters:
  288.  *  pIStorage       LPSTORAGE in which to save.
  289.  *  lVer            LONG providing version number Major (HI) and Minor (Low)
  290.  *
  291.  * Return Value:
  292.  *  LONG            A POLYLINE_E_* value.
  293.  */
  294.  
  295. LONG CPolyline::WriteToStorage(LPSTORAGE pIStorage, LONG lVer)
  296.     {
  297.     ULONG           cb;
  298.     ULONG           cbExpect=0;
  299.     WORD            wVerMaj=HIWORD(lVer);
  300.     WORD            wVerMin=LOWORD(lVer);
  301.     POLYLINEDATA    pl;
  302.     LPSTREAM        pIStream;
  303.     HRESULT         hr;
  304.  
  305.     if (NULL==pIStorage)
  306.         return POLYLINE_E_READFAILURE;
  307.  
  308.     //Get a copy of our data in the version we're going to save.
  309.     DataGet(&pl, lVer);
  310.  
  311.     switch (wVerMaj)
  312.         {
  313.         case VERSIONMAJOR:  //2.x
  314.             switch (wVerMin)
  315.                 {
  316.                 case VERSIONMINOR:  //2.0
  317.                     cbExpect=CBPOLYLINEDATA;
  318.                     break;
  319.  
  320.                 default:
  321.                     break;
  322.                 }
  323.             break;
  324.  
  325.         case 1: //1.x
  326.             switch (wVerMin)
  327.                 {
  328.                 case 0:  //1.0
  329.                     cbExpect=CBPOLYLINEDATA10;
  330.                     break;
  331.  
  332.                 default:
  333.                     break;
  334.                 }
  335.             break;
  336.  
  337.         default:
  338.             break;
  339.         }
  340.  
  341.     if (0==cbExpect)
  342.         return POLYLINE_E_UNSUPPORTEDVERSION;
  343.  
  344.     hr=pIStorage->CreateStream("CONTENTS", STGM_DIRECT | STGM_CREATE
  345.         | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pIStream);
  346.  
  347.     if (FAILED(hr))
  348.         return POLYLINE_E_WRITEFAILURE;
  349.  
  350.     hr=pIStream->Write((LPVOID)&pl, cbExpect, &cb);
  351.     pIStream->Release();
  352.  
  353.     if (FAILED(hr) || cbExpect!=cb)
  354.         return POLYLINE_E_WRITEFAILURE;
  355.  
  356.     return POLYLINE_E_NONE;
  357.     }
  358.  
  359. //End CHAPTER5MOD
  360.  
  361.  
  362.  
  363.  
  364.  
  365. /*
  366.  * CPolyline::ReadFromFile
  367.  *
  368.  * Purpose:
  369.  *  Loads our data (any known version) from a file handle returning
  370.  *  the ver